package com.ruoyi.framework.websocket;

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Component;

/**
 * empNo ：租户ID_用户编号
 */
@Component
@ServerEndpoint("/ws/webSocket/{empNo}")
public class WebSocketServer {
    private static Logger logger = LogManager.getLogger(WebSocketServer.class);
    //静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;
    //concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话，可以使用Map来存放，其中Key可以为用户标识
    private static ConcurrentHashMap<String, WebSocketServer> webSocketSet = new ConcurrentHashMap<String, WebSocketServer>();

    //与某个客户端的连接会话，需要通过它来给客户端发送数据
    private Session session;
    //当前发消息的人员号
    private String empNo = "";

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        try {
            WebSocketServer.onlineCount++;
        } catch (Exception e) {
            logger.error("websocket在线人数统计（上线）异常", e.getMessage());
        }
    }

    public static synchronized void subOnlineCount() {
        try {
            if (WebSocketServer.onlineCount >= 1) {
                WebSocketServer.onlineCount--;
            }
        } catch (Exception e) {
            logger.error("websocket在线人数统计（离线）异常", e.getMessage());
        }
    }

    /**
     * websocket 连接打开
     *
     * @param param
     * @param session
     */
    @OnOpen
    public void onOpen(@PathParam(value = "empNo") String param, Session session) {
        try {
            this.session = session;
            //接收到发送消息的人员编号
            empNo = param;
            this.session = session;
            if (StringUtils.isNotBlank(param) && webSocketSet.get(param) == null) {
                webSocketSet.put(param, this);
                addOnlineCount();
                logger.info(String.format("新连接加入empNo=%s！当前在线人数为%s", empNo, getOnlineCount()));
            }
        } catch (Exception e) {
            logger.error("websocket连接打开异常", e.getMessage());
        } finally {

        }
    }
    @OnMessage
    public void onMessage(String message, Session session) {

    }
    /**
     * websocket 连接关闭
     */
    @OnClose
    public void onClose() {
        try {
            if (StringUtils.isNotBlank(empNo)) {
                webSocketSet.remove(empNo);
                subOnlineCount();
                logger.info(String.format("用户%s连接关闭！当前在线人数为%s", empNo, getOnlineCount()));
            }
        } catch (Exception e) {
            logger.error("websocket连接关闭异常", e.getMessage());
        }
    }

    public void sendMessage(String message) throws IOException {
        //加同步锁，解决多线程下发送消息异常关闭
        synchronized (this.session) {
            this.session.getBasicRemote().sendText(message);
        }
    }
    public boolean onSendByUserId(String message, String UserId) throws IOException {
        if (webSocketSet.get(UserId) != null) {
            Session cSession = webSocketSet.get(UserId).session;
            if (cSession != null && cSession.isOpen()) {
                sendMessage(message, cSession);
                return true;
            }
        }
        return false;
    }


    public void sendMessage(String message, Session session) throws IOException {
        synchronized (session) {
            session.getBasicRemote().sendText(message);
        }
    }

}
